package BackGround;

import java.awt.*;
import java.awt.color.*;
import java.awt.geom.*;

import DistSys.*;
import Element.*;
import Element.Geom.*;
/**
 * Title:
 * Description:
 * Copyright:    Copyright (c) 2002
 * Company:
 * @author
 * @version 1.0
 */

public class BgLine extends AbsElem implements Cloneable {

  public static final String[] LINE_STYLE={"Solid","Dash","Dot","Dash-Dot","Dash-Dot-Dot", "[Keep]"};
  public static final int SOLID=0, DASH=1, DOT=2, DASH_DOT=3, DASH_DOT_DOT=4, KEEP=5;
  public static final float[][] PATTERN;
  static{
      PATTERN = new float[LINE_STYLE.length][];
      PATTERN[SOLID] = new float[]{ 1.0f, 0.0f };
      PATTERN[DASH]  = new float[]{ 15.0f, 5.0f };
      PATTERN[DOT]   = new float[]{ 10.0f, 10.0f };
      PATTERN[DASH_DOT] = new float[]{15.0f, 10.0f, 5.0f, 10.0f};
      PATTERN[DASH_DOT_DOT] = new float[]{15.0f, 10.0f, 5.0f, 10.0f, 5.0f, 10.0f};
  }

  public static BgLine dftBgLine = new BgLine(); //Default line; similar to AbsElem.objActiveTemp

  private int     iThickness;
  private int     iStyle;
  private Color   clrLineColor;

  public BgLine(){
      this.geom = new LineGeom();
      this.geom.setName( "Background Line");
      this.iThickness = 3 ;
      this.iStyle = SOLID;
      this.clrLineColor = Color.gray;
      this.setData(AbsElem.DATA_LAYER, Sys.prjInfo.BG_LINE_LAYER );
  }

  public BgLine( String name, double font, int thick, int style, Color c){
      //only need to create geom object, not RelInd and CktLaw
      this.geom = new LineGeom();
      this.geom.setName(name);
      this.setData(AbsElem.DATA_FONT_SIZE, font);
      this.iThickness = thick ;
      this.iStyle = style;
      this.clrLineColor = c;
      this.setData(AbsElem.DATA_LAYER, Sys.prjInfo.BG_LINE_LAYER );
  }

  public BgLine(  String name, double font, int thick, int style, Color c,
                  int x1, int y1, int x2, int y2){
      this.geom = new LineGeom();
      this.geom.setName(name);
      this.setData(AbsElem.DATA_FONT_SIZE, font);
      this.iThickness = thick ;
      this.iStyle = style;
      this.clrLineColor = c;

      this.geom.x1Stored = x1;
      this.geom.y1Stored = y1;
      this.geom.setNode2FromStored( geom.x1Stored, geom.y1Stored);
      this.geom.x2Stored = x2;
      this.geom.y2Stored = y2;
      this.geom.setNode2FromStored( geom.x2Stored, geom.y2Stored);
      this.setData(AbsElem.DATA_LAYER, Sys.prjInfo.BG_LINE_LAYER );
  }

  public String getName() { return geom.getName(); }
  public double getFontSize() { return getData(AbsElem.DATA_FONT_SIZE); }
  public int getThickness() { return iThickness; }
  public int getStyle() { return iStyle; }
  public Color getColor() { return clrLineColor; }

  public void setName( String s) { geom.setName(s); }
  public void setFontSize(double fontSize) { setData(AbsElem.DATA_FONT_SIZE, fontSize); }
  public void setThickness(int thickness) { this.iThickness = thickness; }
  public void setStyle( int style ) { this.iStyle=style; }
  public void setColor(Color clr) { this.clrLineColor = clr; }

  /**
   * implements Cloneable interface
   */
  public Object clone(){
      BgLine created = new BgLine();

      //copy all (x,y)
      created.setDftTemp(this.getDftTempName());
      created.geom = (LineGeom) ((LineGeom) this.geom).clone();
      created.setName(new String(this.geom.getName()));
      //preventative redundency (next 2 lines)
      created.setData(AbsElem.DATA_LAYER, this.getData(AbsElem.DATA_LAYER) );
      created.setData(AbsElem.DATA_FONT_SIZE, this.getData(AbsElem.DATA_FONT_SIZE));
      created.iThickness= this.iThickness;
      created.iStyle = this.iStyle;
      created.clrLineColor = this.clrLineColor;


      return created;
  }

  public int getType() { return SysConst.TYPE_BG_LINE; }

  /**
   * draw back ground line
   */
  public void draw(Graphics g) {
    /**@todo: implement this Element.AbsElem abstract method*/
    int index = ProjectInfo.BG_LINE_LAYER + ProjectInfo.NUM_BACK_GND_LAYER;
    Layer lyr = (Layer) Sys.prjInfo.layerList.get( index );
    if( lyr.getMode() == Layer.OFF ) return;

    Color oldColor = g.getColor();
    Font oldFont = g.getFont();

    //draw line ; if selected draw it in yellow.
    if( lyr.getMode() == Layer.GRAY ) { g.setColor( Color.gray ); }
    else if( Sys.selectedList.contains(this) ) { g.setColor( Color.yellow ); }
    else { g.setColor( this.getColor() ); }
    Graphics2D g2=(Graphics2D) g;
    BasicStroke dftBS = (BasicStroke) g2.getStroke();
    BasicStroke newBS = new BasicStroke(  this.iThickness,
                                          BasicStroke.CAP_BUTT, //dftBS.getEndCap();
                                          dftBS.getLineJoin(),
                                          dftBS.getMiterLimit(),
                                          PATTERN[ this.iStyle ], //line style
                                          dftBS.getDashPhase()
                                       );
    g2.setStroke( newBS);      //update stroke
    g2.drawLine(geom.x1, geom.y1, geom.x2, geom.y2);

    g2.setStroke(dftBS);       //set stroke back to default one
    g.setFont( oldFont);
    g.setColor( oldColor);
  }//end of draw()

  // Dummy implementation of the abstract method since we inherit draw(g)
  public void draw(Graphics2D g2, double dist, double theta) { }

  public void drawFrame(Graphics g){
      if( iThickness <= 3 ) {
          super.drawFrame(g);
      } else {
          //do nothing since iThickness is thick enough
      }
  }

  public void drawForMove( Graphics g){
      super.drawForMove(g);
  }

  public void drawHighLights(Graphics g){
      //do nothing
  }

  public void drawNodes( Graphics g){
    //always draw nodes in black based on active layer, not on Sys.showNode
    int d=SysConst.NODE_SIZE;
    g.setColor( Color.black);
    g.fillRect(geom.x1-d/2, geom.y1-d/2, d, d); //starting dot
    g.fillRect(geom.x2-d/2, geom.y2-d/2, d, d); //ending dot
  }

  //draw text
  public void drawText( Graphics g){
      int index = ProjectInfo.BG_LINE_LAYER + ProjectInfo.NUM_BACK_GND_LAYER;
      Layer lyr = (Layer) Sys.prjInfo.layerList.get( index );
      if( lyr.getMode() == Layer.OFF ) return;

      if( lyr.getMode() == Layer.GRAY ) { g.setColor( Color.gray ); }
      else { g.setColor( Color.black); }

      int x= Math.min( geom.x1, geom.x2);
      int y= (geom.y1 + geom.y2)/2;
      int fontSize = (int) (this.getData(AbsElem.DATA_FONT_SIZE) *
                            Sys.prjInfo.dZoomFactor /8.0 ); //8 ==default MapSF
      if( fontSize >= 2 ){
          g.setFont( new Font("Dialog", Font.PLAIN, fontSize) );
          g.drawString( this.geom.getName(), x, y);
      }
  }//end of drawText()


    /**
     * Returns whether the data field with the given index "makes sense" for
     * this element type or not.
     *
     * @param index  a <code>int</code> specifying the index.
     *
     * @return  <code>true</code> if the data field "makes sense",
     *          <code>false</code> otherwise
     */
    public boolean getDataExists(int index) { return false; }

    /**
     * Returns whether the result field with the given index "makes sense" for
     * this element type or not.
     *
     * @param index  a <code>int</code> specifying the index.
     *
     * @return  <code>true</code> if the result field "makes sense",
     *          <code>false</code> otherwise
     */
    public boolean getResultExists(int index) { return false; }
}